<?php
/**
 * Defines the way variable expressions are converted into PHP before rendering. Variable expressions are needed to eliminate echoing through scripting in HTML view. They are 
 * modeled on JSP Expression Language (EL), with a number of differences centered on strict pattern enforcing as well some simplifications:
 * - they strictly follow dotted syntax. While JSP allows accessing properties as ${class[property]}, here you can only access them as ${class.propriety} 
 * - they contain nothing but variable expressions. While JSP allows putting conditional logic within EL, such as ${class.propriety==2}, here you must put conditional logic outside
 * as $[class.propriety}==2. For latter to be interpreted as PHP, you must put this conditional expression within a 'condition' attribute in a if/elseif tag (See: Tag libraries).
 * - they can be nested 
 */
class ExpressionParser {
	/**
	 * Looks for variable expressions in string, passes them to parseCallback and returns an answer where each found match is converted to PHP.
	 * 
	 * Example:
	 * $strSubject		
	 * 
	 * @param string $strSubject
	 * @return string
	 */
	public function parse($strSubject) {
		if(strpos($strSubject,'${')===false) return $strSubject;
		return preg_replace_callback("/[\$]\{((?:(?>[^{}]+?)|(?R))*?)\}/",array($this,"parseCallback"),$strSubject);
	}
	
	/**
	 * Converts variable expression to PHP variable and performs echo on that variable.
	 * 
	 * @param array $tblMatches
	 * @return string
	 */
	protected function parseCallback($tblMatches) {
		return '<?php echo '.$this->convertToVariable($tblMatches[0]).'; ?>';
	}
	
	/**
	 * Converts variable expression into a PHP variable
	 * 
	 * @param string $strDottedVariable
	 * @return string
	 */
	protected function convertToVariable($strDottedVariable) {
		if(strpos($strDottedVariable,".")===false) {
			return str_replace(array("{","}"),"",$strDottedVariable);
		} else {
			return preg_replace(array('/\$\{([a-zA-Z0-9_]+)\./','/\}/','/\./','/\[([a-zA-Z0-9_]+)\]/'),array('$$1[',']','][','["$1"]'),$strDottedVariable);
		}
	}
}